home *** CD-ROM | disk | FTP | other *** search
- #!/bin/sh
-
- # LPR2 -- Utility to print postscript document on both sides.
- VERSION='1.2e'
-
-
- ######################## LEGAL STUFF, LICENSE, ET AL. #########################
-
- # COPYLEFT NOTICE:
- # Copyright (c) 1994 Franτois-RenΘ "FarΘ" BΓn Rideau DDa(.ng-Vu~
- # (rideau@ens.fr,rideau@frmap711.mathp7.jussieu.fr)
-
- # LICENSE AGREEMENT:
- # This program is distributed under *modified* the terms of the
- # GNU General Public License (any official version you can find).
- # Particularly,
- # 0) You are mostly free to use and redistribute this program.
- # 1) there is absolutely NO WARRANTY about what effect it can have
- # on your software or hardware.
- # 2) you may strip off any comment or useless characters and statements
- # from this file, but only for personal use. But you shall not distribute
- # a modified or stripped version.
- # Just below are my modifications to the GPL...
-
- # SMILEWARE
- # This program is smileware:
- # 1) if you use this program several times, if you modify it, or enhance it
- # in any way, you should send me a note, letter, postcard, or even just an
- # e-mail. This note should contain your feedback about your using this
- # program, suggestions about improvements, enhancements, etc, if you have any.
- # But even if you don't, a note/card/etc with just some kind words or a smiley
- # is welcome.
- # 2) if you use this program regularly, or reuse it more than three months
- # after you originally used it, I morally bind you to pay for it.
- # The exact amount you pay is up to you, but it shouldn't be less than one
- # hundredth of what a typical commercial program costs near you, and not less
- # than the expenses incurred for paying. Once you determined how much to pay,
- # you should do one of the following with that money:
- # a) give it all to the next beggar you meet (ain't there one just round the
- # corner ?); if you think it's too much money for you to give him, well,
- # firstly, you're paying for this program, so consider it's me giving your
- # money to the beggar, and second, it will be fun to you to look his reaction.
- # b) if you really don't want to give this money to this beggar, or if there's
- # no beggar where you live, send your money to any charitable or ecological
- # organization you *know* to be honest.
- # c) if you won't give to a beggar, and don't trust any charitable or
- # ecological organization, then send it to me, and I'll do it myself.
- #
- # My addresses are at the end of these comments.
-
-
- ########################### DESCRIPTION AND HELP #############################
-
- # WHAT LPR2 IS MEANT TO BE:
- # To save paper, and lighten you backpack, without lightening your purse by
- # buying printers that already print documents on both sides, do use this
- # program to print double sided documents.
- # Not throwing away paper is good for just everyone throughout the world.
- # Stop the spillage, help save the world, use LPR2 !
- # Enhanced version 1.2 now works with *all* documents I've tried it with !!!
-
- # WHAT LPR2 IS *NOT* MEANT TO BE:
- # This program is NOT a full-featured program for manipulating postscript
- # documents either. mpage, psutils, and commercial software from Adobe will do
- # that for you. However, I've not tried commercial software, but all the free
- # utilities I could find. And for the majority of the documents I've tried
- # to manipulate, that I got from throughout the Internet (papers that were
- # written using various software), none of these utilities would work properly:
- # and wanted to print: sometimes it wouldn't work at all, or it would
- # mirror the page, lose font information, or choke in the middle of the
- # document (typically near the place some postscript documents was imported
- # in the original paper: figure, picture, etc). LPR2 won't replace the
- # multipage "n-up" features from the previous utilities (well it could be done,
- # but not without a careful study of postscript), but at least it will provide
- # a page selection mechanism that works on all reasonable documents: LPR2 has
- # never failed on any published document it has been tried with yet (but it
- # would be trivial to write some program specifically for lpr2 to fail).
- # This program is NOT a "standalone" postscript interpreter either.
- # You still need another PostScript interpreter to get it to work. The
- # interpreter is typically just your PostScript printer, or GhostScript,
- # or whatever. If you have a non-PostScript printer, the Printing-HOWTO
- # (somewhere on all Linux sites) will explain you how to set up "lpr" to
- # work with PostScript documents anyway, using GhostScript as the interpreter
- # (that's free software).
-
- # WHERE TO FIND THE LATEST VERSION
- # The latest version should be available by anonymous ftp:
- # * on "ftp://sunsite.unc.edu/pub/Linux/" and mirror linux sites,
- # in subdirectory "system/Printing/"
- # * on my own ftp site, "ftp://frmap711.mathp7.jussieu.fr/pub/scratch/rideau/"
- # in subdirectory "lpr2/"
- # * if you know any site where people would look for such programs, please
- # tell me, so I can spread this utility.
-
- # HOW IT WORKS:
- # The shell part is only a wrapper to accept all the different options.
- # The core of the program (the shell function redefshowpage) prepends some
- # PostScript code to the file to print, that redefines "showpage" so that it
- # will print every other page. According to the new showpage skipping the
- # first page or not, we obtain one document for recto sides, and one another
- # for verso sides. We then have to print it all...
- # Note that as the program redefines *global* variables, it cannot be
- # recursively called. But as the page selection function is programmable,
- # such use isn't needed. If you know how to reliably use local variables
- # in postscript, please tell me.
- # There should not be any clash with variables from the postscript file to
- # be printed; if however there was one, you can still modify those names in
- # the postscript part of lpr2.
-
- # INSTALLATION PROCEDURE:
- # - gunzip lpr2
- # - chmod 0755 lpr2
- # - mv lpr2 /somewhere_in_my_PATH/bin/
- # - edit the file to customize if need be (look for !!!! marks):
- # the LPR= line should contain the name of a command or function that
- # will print its PostScript standard input. I put "lpr" as the default.
- # - Enjoy !
-
- # USAGE:
- # To print document "doc.ps", print odd pages on one side and even pages on
- # the other.
- #
- # My HP LaserJet 4ML printer issues pages in the "right" order, i.e. the
- # page on top exits on top. I also have to feed paper with verso (back) upward,
- # and top of sheet near me. Thus, I have to print even pages first, then odd
- # pages. That's what the default behaviour is.
- #
- # Rainer Blome (rainer@physik3.gwdg.de) says:
- ## My default `PostScript' printer, an HP LJ III, does emit pages in the
- ## `right' order (small page numbers on top), but does not feed verso. a
- ## stack of paper exits the printer exactly the same configuration as it has
- ## been put in the paper cassette.
- ## To get the desired result, however, i need the pages in this order, yes,
- ## but the empty side has to be in the position that will be printed on. the
- ## HP IV does that automatically, each page is reversed on every printing.
- ## Thus, `print on reverse side' with `emit in right order' is OK, as is
- ## `print on topside' with `emit in wrong order'. other combinations require
- ## reordering/reversal by hand.
- #
- # If you need some other behaviour, please tell me or correct it and send
- # me feedback.
- #
- # Beware that there may be one odd page more than even pages. Sheets must be
- # fed with verso on top. Default option (--all) does it.
- #
- # Thus, the usage is: feed blank sheets to the printer, mark one corner with
- # a pencil to see how you will have to feed sheets again to print the other
- # side. Then, print even pages. Insert printed pages back into the printer
- # in the right order and side, as determined by the pencil, and
- # print odd pages.
-
- # MISFEATURES:
- # First of all, this is a mixed /bin/sh and Postscript program; the existence
- # of such languages is a bug in itself. Please send feedback to God so that
- # this state of things changes.
- # Because it uses /bin/sh, this program cannot reliably work with files
- # whose name contain spaces, carriage returns, null characters, etc. But this
- # is the case for most unix programs, so lpr2 is not *particularly* limiting
- # in such sense.
- # There is no soundness testing for the -p option, so beware and stick to
- # the syntax; however, an error will most probably result in a run-time error
- # at execution of the postscript program, so the document will be rejected
- # without any page being printed.
-
- # INVOCATION: lpr2 [options] files
- #
- # option what it means
- # -1,-o,--odd "print only odd pages"
- # -2,-e,--even "print only even pages"
- # -c,--cond "the string just after this is the postscript condition for
- # a page to be printed, e.g. '4 eq'"
- # -s,--select "print only the page whose number follows '-s' "
- # -p,--pages "print the pages listed after -p
- # in a comma-separated list of the form i-j[%k],
- # where i and j are first and/or last pages,
- # and k is a step. -- not implemented"
- # -a,--all "print even pages; prompt; print odd pages" (default)
- # -P,--print "do send to printer, not to standard output"
- # -N,--noprint "do not send to printer, but to standard output" (default)
- # -r,--reverse "print odd pages; prompt; print even pages in reverse
- # order" (beware: remove last sheet if odd number of pages)
- # NOT IMPLEMENTED YET, and not to be soon, as it involves much
- # more than just a postscript header. Use mpage or psrev (from
- # the psutil package) if you need such thing. Unhappily, those
- # packages are far less reliable than lpr2 v1.2
- # -z define the printing program to be following argument
- # e.g. -z lpr or -z cat
- # -Z following argument is to pass to the printing program
- # e,g, -Z "-lpr_option -second_lpr_option"
- # -- stop parsing options: all the remaining arguments are filenames.
-
- # THE AUTHOR:
- # I'm no PostScript guru *at all*. It's my first (and certainly last)
- # PostScript program. I've never read any Postscript book or official
- # documentation or programming recommendation; only gs manpage and
- # examples. Postscript looks like a very interesting language to me;
- # very FORTH-like indeed. But whoever defined such lame semantics for binding
- # only deserves shame.
- # I developped this program under Linux using Ghostscript 2.6.1 in five
- # minutes. I've actually spent much more time documenting it and transforming
- # it into a shell utility than I did writing the postscript stuff. Just try
- # to evaluate and compare the size of the postscript part, the size of the
- # shell script part, and the size of the comments ;-)
-
- # HOW WELL THE PROGRAM SHOULD BEHAVE:
- # This program works very well for me.
- # - you need a shell that supports shell functions (SYSV or SunOS shells do,
- # while Ultrix shell doesn't). If yours doesn't work, try getting ksh, bash or
- # better even, *zsh* (use option -fy for sh emulation) from the net.
- # - The program should work on any well-behaved PostScript document (i.e. the
- # kind of documents standard applications produce), but is reported to fail
- # when used in combination with some dirty Postscript utilities. mpage by
- # Mark P. Hahn 1988 is such dirty program that fails :( :(. Happily, newer
- # versions of mpage already support page selection, so when mpage works,
- # lpr2 is not needed.
- # - You should be able to refeed the printer with its first output, and of
- # course, be sure that no one else will use the printer while you are feeding
- # the printer with the output for the verso side of the documents.
- # - If your printer output pages in the reverse order, you're in for a double
- # session of reordering pages :( :( :(
-
- # HISTORY:
- # version 0.0: just postcript code manually prepended to a document.
- # developped with ghostscript.
- # version 0.1: the same, but working (with the discovery of erasepage)
- # version 1.0: a script that doesn't even work (I'm ashamed of that)-8
- # version 1.1: the same, but bugs fixed:
- # - cat <<"END" was used instead of cat<<END,
- # and did not expand $1.
- # - %! was forgotten on the first line of the document,
- # which can make auto-detection of file format fail for lpr2
- # documents.
- # - "echo lpr" was also done instead of lpr :(
- # And a new feature added:
- # - if "-" or no file is given, lpr2 will work even with option
- # "--all", by saving input in a file to reread it the second
- # time. Exit and signals are trapped to rm it.
- # version 1.1b: Help was increased thanks to the kind feedback of
- # Warwick Hockley <hock@adhoc.apana.org.au>.
- # Help options are supported.
- # version 1.1c: bugs corrected: quotes not closed >8 ; run-time message
- # modified
- # version 1.1d: added arbitrary page selection
- # version 1.2: used the ps2ppm PageCount trick using strings to escape
- # save/restore sequences. lpr2 now works with all files
- # I've tried it with !
- # version 1.2b: Just understood why ps2ppm added 1000000 to page count.
- # lpr2 now works after page 9 :)
- # version 1.2c: added nicer page selection: page can be named as p...
- # version 1.2d: merged feedback from Rainer Blome (rainer@physik3.gwgd.de):
- # - removed the -P,--print "I changed my mind. Do print" option
- # because it conflicted with a common printer option.
- # - extended the description of how to reinsert paper.
- # version 1.2e: - added the -p option
- # - replaced the default behavior (print) by printing to stdout
- # if any option is present. Restored option -P, with options
- # -z and -Z to select printing command and default option
- # behavior to "unknown option" instead of passing it blindly
- # to lpr.
-
- # TO DO
- # - if we know some upper bound to the last page to be printed, put some
- # "end execution" Postscript instruction for when this page is reached;
- # of course, I should first find how this can in done in PostScript :)
-
- # AUTHOR'S .SIGNATURE AND ADDRESSES:
- #- , , _ v ~ ^ --
- #- Fare -- rideau@clipper.ens.fr -- Francois-Rene Rideau -- +)ang-Vu Ban --
- #- ' / . --
- #MOOSE project member. OSL developer. | | /
- #Dreams about The Universal (Distributed) Database. --- --- //
- #Snail mail: 6, rue Augustin Thierry 75019 PARIS FRANCE /|\ /|\ //
- #Phone: 033 1 42026735 /|\ /|\ /
- #Join the TUNES project for a computing system based on computing freedom !
- # TUNES is a Useful, Not Expedient System
- #WWW page at URL: "http://www.eleves.ens.fr:8080/home/rideau/Tunes/"
-
-
- ########################## The Postscript stuff ##############################
- redefshowpage ()
- {
- # have as argument condition on page to show
- cat <<-END
- %!PS-Adobe-3.0
-
- /.show.this.page.p { $1 } bind def
- /.page.number 1000001 7 string cvs def
- /.showpage.orig /showpage load def
- /.erasepage /erasepage load def
- /.showpage.lpr2 {
- 2 dict begin
- /p .page.number dup cvi dup 1 add 3 2 roll cvs pop 1000000 sub def
- mark p
- % (lpr2: showpage called for page ) print dup =only (.\n) print flush
- .show.this.page.p
- /c exch def cleartomark c
- end
- { % (lpr2: showing page.\n) print flush
- .showpage.orig }
- { % (lpr2: skipping page.\n) print flush
- .erasepage }
- ifelse
- % (lpr2: showpage ended.\n) print flush
- } def
-
- %Redefine showpage...
- /showpage { .showpage.lpr2 } bind def
-
- END
- }
-
-
- ########################## The shell functions ##############################
- doprinteven ()
- {
- (redefshowpage "2 mod 0 eq" ; cat $FILES) | $SENDJOB
- }
-
- doprintodd ()
- {
- (redefshowpage "2 mod 1 eq" ; cat $FILES) | $SENDJOB
- }
-
- doprintcond ()
- {
- (redefshowpage "$COND" ; cat $FILES) | $SENDJOB
- }
-
- prompt ()
- {
- echo "$@" > /dev/tty
- read dummy_answer < /dev/tty
- }
-
- doall ()
- {
- prompt '
- Feed the printer with blank sheets.
- If you don'"'"'t how to feed the printer again to achieve printing on
- the "right" side, mark corners of the first sheets with a pencil.
-
- When you'"'"'re done, press "Enter".
- '
- doprinteven
- prompt '
- First, do wait for the thing to have been printed.
- When it'"'"'s done, press "Enter".
- '
- prompt '
- Now, if your printer issues pages in the wrong order, you have a problem.
- You'"'"'ll have to reorder everything twice. Next time, try --reverse option
- if it'"'"'s implemented.
-
- The first thing to do after having recovered the back sides of your printed
- documents is to ensure that no one else will use the printer while you'"'"'re
- printing on the other side.
- When this is done, feed the printer back with the same sheets, but
- place the sheets so that the other side will be printed (with the same top
- of page). If your document has an odd number of page, add a blank sheet at
- the end.
- When you'"'"'re done, press "Enter".
- '
- doprintodd
- }
-
- doreverse ()
- {
- echo "NOT IMPLEMENTED YET" >&2
- exit 4
- }
-
- calllpr ()
- {
- $LPR $LPROPTS
- }
-
- cleanexit () {
- $RM $FILE
- exit 1
- }
-
-
- ComputeEachCOND () {
- C_COND_0 $1
- COND="$COND1"
- shift
- for i ; do
- C_COND_0 $i
- COND="$COND"'
- '"$COND1 or"
- done
- }
-
- C_COND_0 () {
- case "$1" in
- "-%"*) : a ; IFS=" -%" ; C_COND_1 1 x $1 ;;
- "-"*"%"*) : b ; IFS=" -%" ; C_COND_1 1 $1 ;;
- *"-%"*) : d ; IFS=" -%" ; C_COND_2 $1 ;;
- *"-"*"%"*) : e ; IFS=" -%" ; C_COND_1 $1 ;;
- "-"*) : c ; IFS=" -%" ; C_COND_1 1 $1 1 ;;
- *"%"*) : f ; IFS=" -%" ; C_COND_2 $1 ;;
- *"-") : g ; IFS=" -%" ; C_COND_1 $1 x 1 ;;
- *"-"*) : h ; IFS=" -%" ; C_COND_1 $1 1 ;;
- "%"*) : i ; IFS=" -%" ; C_COND_1 1 x $1 ;;
- *) : j ; IFS=" -%" ; C_COND_1 $1 $1 1 ;;
- esac
- }
-
- C_COND_1 () {
- C_COND_n $*
- }
-
- C_COND_2 () {
- C_COND_m $*
- }
-
- C_COND_m () {
- C_COND_n $1 x $2
- }
-
- C_COND_n () {
- IFS=" "
-
- if [ "$1" = "$2" ] ; then
- COND1="p $1 eq"
- else
- if [ "$1" != 1 ] ; then
- COND1="p $1 ge"
- if [ "x$2" != "xx" ] ; then
- COND1="$COND1 p $2 le and"
- fi
- else
- if [ "x$2" != "xx" ] ; then
- COND1="p $2 le"
- else
- COND1=true
- fi
- fi
- fi
- if [ "$3" != 1 ] ; then
- COND1="$COND1 p $1 sub $3 mod 0 eq and"
- fi
- }
-
-
- ComputeCOND () {
- IFS=" ," ; ComputeEachCOND $1
- IFS=" "
- }
-
- ######################### The command line interface ########################
- LPR="lpr" # !!!! replace with your standard printing command
- # may be just "cat > /dev/lp1". lpr should be fine.
- RM="rm" # !!!! replace with your standard file deletion command
- # may be "/bin/rm -f -", but rm should be fine.
-
- # These should be ok and not need any modification
- TODO=doall
- LPROPTS=
- FILES=
- SENDJOB=cat # calllpr
-
- ParseOpts () {
- GOTOPTS=n
- while [ -n "$*" ] ; do
- i="$1" ; shift
- case "$i" in
- -a|--all) GOTOPTS=y ; TODO=doall ; SENDJOB=calllpr ;;
- -r|--reverse) GOTOPTS=y ; TODO=doreverse ; SENDJOB=calllpr ;;
- -N|--noprint) GOTOPTS=y ; SENDJOB=cat ;;
- -P|--print) GOTOPTS=y ; SENDJOB=calllpr ;;
- -1|-o|--odd) GOTOPTS=y ; TODO=doprintodd ;;
- -2|-e|--even) GOTOPTS=y ; TODO=doprinteven ;;
- -c|--cond) GOTOPTS=y ; TODO=doprintcond ; COND="$1" ; shift ;;
- -s|--select) GOTOPTS=y ; TODO=doprintcond ; COND="$1 eq" ; shift ;;
- -p|--pages) GOTOPTS=y ; TODO=doprintcond ; ComputeCOND $1 ; shift ;;
- -z) GOTOPTS=y ; LPR="$2" ; shift 2 ;;
- -Z) GOTOPTS=y ; LPROPTS="$LPROPTS $2" ; shift 2 ;;
- --) FILES="$FILES $*" ; shift $# ;;
-
- -v) echo "LPR2 v$VERSION" ; exit 0 ;;
- -V|--version) echo "LPR2 -- version $VERSION" ; exit 0 ;;
- -h|-"?"|--help) echo "Run command \`\`more $0''" \
- "for help about this program."
- exit 0 ;;
- -*) echo "Unknow option \`\`$i''." >&2
- echo "Read file $0 for help." >&2
- exit 3 ;;
- *) FILES="$FILES $i" ;;
- esac
- done
- if [ "$GOTOPTS" = "n" ] ; then TODO=doall ; SENDJOB=calllpr ; fi
- }
-
- DoIt () {
- : '":" is for debugging'
- : LPR=$LPR
- : TODO=$TODO
- : SENDJOB=$SENJOB
- : LPROPTS=$LPROPTS
- : FILES=$FILES
- case "$SENDJOB$TODO$FILES" in
- catdoall*|catdoreverse*)
- echo "Incompatible options" ;
- exit 1 ;;
- calllprdoall*" - "*|calllprdoreverse*" - "*|calllprdoall|calllprdoreverse)
- FILE=/tmp/lpr2-$$
- trap cleanexit EXIT HUP TERM
- cat > $FILE
- FILES=$FILE $FILES
- $TODO
- ;;
- *) $TODO
- ;;
- esac
- }
-
- ParseOpts "$@"
- DoIt
-